﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;



namespace Bildverarbeitung
{
    public class KuebrichAndiFilter: IFilter
    {            
        public Bitmap GetSummerizedDifferencefromAverage(Bitmap[] sources)
        {
            BitmapData[] bitmapData = new BitmapData[sources.Length];

            Bitmap result = new Bitmap(sources[0].Width, sources[0].Height);
            BitmapData resultData = result.LockBits(new Rectangle(0, 0, sources[0].Width, sources[0].Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

            unsafe
            {
            byte*[] ptr = new byte*[sources.Length];
            for (int i = 0; i < sources.Length; i++)
            {
                bitmapData[i] = sources[i].LockBits(new Rectangle(0, 0, sources[0].Width, sources[0].Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                ptr[i] = (byte*)bitmapData[i].Scan0.ToPointer();
            }

            int lineSize = sources[0].Width * 3;

            byte* resultPtr = (byte*)resultData.Scan0.ToPointer();

                    // for each line
            for (int y = 0; y < sources[0].Height; y++)
            {
                int wert_R = 0, wert_G = 0, wert_B = 0;

                // for each pixel
                for (int x = 0; x < lineSize; x+=3)
                {
                    for (int i = 0; i < sources.Length; i++)
                    {
                        wert_R += *(ptr[i]);
                        wert_G += *(ptr[i] +1);
                        wert_B += *(ptr[i] +2);
                    }

                    wert_R /= sources.Length;
                    wert_G /= sources.Length;
                    wert_B /= sources.Length;

                    byte help_dif_r = 255;
                    byte help_dif_g = 255;
                    byte help_dif_b = 255;

                    byte help_r = 0;
                    byte help_g = 0;
                    byte help_b = 0;

                    for (int i = 0; i < sources.Length; i++)
                    {
                        byte tmpr = (byte) Math.Abs(*ptr[i] - wert_R);
                        byte tmpg = (byte) Math.Abs(*(ptr[i]+1) - wert_G);
                        byte tmpb = (byte) Math.Abs(*(ptr[i]+2) - wert_B);

                        if (tmpr < help_dif_r) { help_r = *ptr[i]; help_dif_r = tmpr; }
                        if (tmpg < help_dif_g) { help_g = *(ptr[i]+1); help_dif_g = tmpg; }
                        if (tmpb < help_dif_b) { help_b = *(ptr[i]+2); help_dif_b = tmpb; }
                        
                        ptr[i]+=3;
                    }

                    *resultPtr = help_r;
                    resultPtr++;
                    *resultPtr = help_g;
                    resultPtr++;
                    *resultPtr = help_b;
                    resultPtr++;
                }
            }
            }

            result.UnlockBits(resultData);
            /////////////////
            return result;
        }

        public String GetName()
        {
            return ("KuebrichAndi");
        }
    }
}
